package com.hoperun.udpbroadcast.broadcast;

import com.hoperun.udpbroadcast.Log;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class UdpBroadcastServer {

    EventHandler eventHandler;
    private int broadcastPort = 8888;     //端口
    DatagramSocket socket;

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    private ArrayList<String> receiveArray = new ArrayList<>();
    private Callback callback;

    public interface Callback {
        void receive(String address, String receive);
    }

    public UdpBroadcastServer(int port) {
        this.broadcastPort = port;
        eventHandler = new EventHandler(EventRunner.create());
        eventHandler.postTask(this::receive);
    }

    public void setSocket(DatagramSocket socket) {
        this.socket = socket;
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    private void receive() {
        if (socket == null) {
            try (DatagramSocket datagramSocket = new DatagramSocket(broadcastPort)) {
                receiveSocket(datagramSocket);
                eventHandler.postTask(this::receive);
            } catch (IOException e) {
                e.printStackTrace();
                Log.w("receive", e);
            }
        } else {
            try {
                receiveSocket(socket);
                eventHandler.postTask(this::receive);
            } catch (IOException e) {
                e.printStackTrace();
                Log.w("receive", e);
            }
        }
    }

    private void receiveSocket(DatagramSocket socket) throws IOException {
        Log.println("  receive -->port:%s, address:%s, localPort:%s", socket.getPort(), socket.getLocalAddress(), socket.getLocalPort());
        byte[] ackBuf = new byte[1024];
        DatagramPacket ackPacket = new DatagramPacket(ackBuf, ackBuf.length);
        socket.receive(ackPacket);
        String receiveStr = new String(ackPacket.getData(), StandardCharsets.UTF_8).trim();
        String receiveIP = ackPacket.getAddress().getHostAddress();
        if (callback != null) {
            callback.receive(receiveIP, receiveStr);
        }

        appendReceive(receiveIP + " -->" + receiveStr);
    }

    public void appendReceive(String str) {
        String time = simpleDateFormat.format(new Date());
        String builder = time + " : " + str;
        receiveArray.add(builder);
        Log.println("appendReceive %s", builder);
    }

    public String getLast() {
        return receiveArray.get(receiveArray.size() - 1);
    }

    public String getReceiveString() {
        return String.join("\n", receiveArray);
    }
}
